import re
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth import login, authenticate,logout
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from django import http
from django.db import DatabaseError
from django_redis import get_redis_connection

from apps.users.models import User
from meiduo_mall_two.utils.response_code import RETCODE

# Create your views here.

###########用户名重复注册##########
class UsernameCountView(View):
    def get(self,request,username):
        # 接收参数  username
        # 验证参数  正则
        # 实现核心逻辑
        count = User.objects.filter(username=username).count()
        # 返回响应
        return http.JsonResponse({"code":RETCODE.OK,"errmsg":"OK","count":count})

##########手机号重复注册###########
class MobileCountView(View):
    def get(self,request,mobile):
        # 实现核心逻辑
        count = User.objects.filter(mobile=mobile).count()
        return http.JsonResponse({"code":RETCODE.OK,"errmsg":"OK","count":count})

##########用户注册################
class RegistserView(View):
    def get(self,request):
        '''提供用户注册'''
        return render(request,"register.html")

    def post(self,request):
        # 1. 接受参数  前端是什么请求方式,就用什么请求方式
        username = request.POST.get("username")
        password = request.POST.get("password")
        password2 = request.POST.get("password2")
        mobile = request.POST.get("mobile")
        # 校验手机验证码
        sms_code_client = request.POST.get("sms_code")
        allow = request.POST.get("allow")
        # 2.校验参数
        # 判断参数是否齐全
        if not all([username,password,password2,mobile,allow]):
            return http.HttpResponseForbidden("缺少必传参数")
        # 判断用户名
        if not re.match(r"^[a-zA-Z0-9_-]{5,20}$",username):
            return http.HttpResponseForbidden("用户名错误")
        # 判断密码是否符合
        if not re.match(r"^[a-zA-Z0-9]{8,20}$",password):
            return http.HttpResponseForbidden("请输入8-20位字符的密码")
        # 判断密码是否一致
        if password != password2:
            return http.HttpResponseForbidden("密码不一致")
        # 判断手机号
        if not re.match(r"^1[3-9]\d{9}$",mobile):
            return http.HttpResponseForbidden("请输入正确的手机号码")

        # 判断用户输入的验证码和服务端的是不是一样
        # 连接redis
        redis_conn = get_redis_connection("verify_code")
        # 从redis中提取服务器的手机验证码
        sms_code_server = redis_conn.get("sms_%s" % mobile)
        if not sms_code_server:
            return render(request,"register.html",{"sms_code_errmsg":"短信验证码失效"})
        # 因为服务器的验证码时bytes类型,所以要decode解码成字符串
        if sms_code_client != sms_code_server.decode():
            return render(request,"register.html",{"sms_code_errmsg":"短信验证码有误"})

        # 判断是否勾选协议
        if allow != "on":
            return http.HttpResponseForbidden("请勾选用户协议")

        # 实现核心逻辑: 保存用户注册数据
        # 用Django 自带的用户认证系统,会对密码进行加密
        try:
            user = User.objects.create_user(username=username,
                                            password=password,
                                            mobile=mobile)
        except DatabaseError:
            return render(request,"register.html",{"register_errmsg":"注册失败"})

        # 状态保持
        login(request,user)

        # return redirect(reverse("contents:index"))

        # 注册成功之后,将用户名写入cookie
        response = redirect(reverse("contents:index"))
        response.set_cookie("username",user.username,max_age=3600*24*14)

        # 响应结果
        return response


#########用户登陆#################
class LoginView(View):
    def get(self,request):
        """展示用户登陆界面"""
        return render(request,"login.html")

    def post(self,request):
        """实现用户登陆逻辑"""
        #　接收参数
        username = request.POST.get("username")
        password = request.POST.get("password")
        remembered = request.POST.get("remembered")

        # 校验参数
        # 判断参数是否齐全,是否记住密码是可选,所以不用校验
        if not all([username,password]):
            return http.HttpResponseForbidden("缺少参数")
        # 判断用户名是否是5-20个字符
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseForbidden('请输入正确的用户名或手机号')
        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('密码最少8位，最长20位')

        # 认证用户
        user = authenticate(request,username=username,password=password)
        if not user:
            return render(request,"login.html",{"account_errmsg":"账号或密码错误"})

        # 状态保持
        login(request,user)

        # 根据用户是否记住登陆,来设置生命周期
        if remembered != "on":
            # 不记住登陆,浏览器会话结束后,状态保持销毁
            request.session.set_expiry(0)
        else:
            # None 默认两周
            request.session.set_expiry(None)

        # 返回
        # return redirect(reverse("contents:index"))

        # 登陆成功之后,将用户名写入cookie
        response = redirect(reverse("contents:index"))
        response.set_cookie("username",user.username,max_age=3600*24*14)

        # 登陆成功后重定向到其他页面
        next = request.GET.get("next")
        if next:
            # 跳转到对应页面
            response = redirect(next)
        else:
            response = redirect(reverse("contents:index"))

        # 响应结果
        return response



#########退出登陆#################
class LogoutView(View):

    def get(self,request):
        # 清理状态保持
        logout(request)
        # 重定向到首页
        response = redirect(reverse("contents:index"))
        # 清理cookie中的用户名
        response.delete_cookie("username")
        # 返回结果
        return response


#########用户中心#################
class UserInfoView(LoginRequiredMixin,View):
    """用户中心"""
    def get(self,request):
        return render(request,"user_center_info.html")




